// my_net_device.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/skbuff.h>

#define MY_NET_DEV_NAME "my_net_device"

// 网络设备结构体
struct my_net_device {
    struct net_device *netdev;
    struct napi_struct napi;
};

// 发送数据包
static netdev_tx_t my_net_device_start_xmit(struct sk_buff *skb, struct net_device *netdev) {
    // 这里可以添加发送数据包的代码
    printk(KERN_INFO "Sending packet: %p\n", skb->data);

    // 释放 skb
    dev_kfree_skb(skb);
    return NETDEV_TX_OK;
}

// 接收数据包
static int my_net_device_rx(struct my_net_device *dev) {
    struct sk_buff *skb;
    struct net_device *netdev = dev->netdev;

    // 模拟接收一个数据包
    skb = netdev_alloc_skb(netdev, 1500);
    if (!skb) {
        return -ENOMEM;
    }

    // 填充 skb 数据
    skb_put(skb, 1500);
    memcpy(skb->data, "Hello from my_net_device", 25);
    skb->protocol = eth_type_trans(skb, netdev);
    netif_rx(skb);

    return 0;
}

// NAPI poll 函数
static int my_net_device_poll(struct napi_struct *napi, int budget) {
    struct my_net_device *dev = container_of(napi, struct my_net_device, napi);
    int work_done = 0;

    // 模拟接收数据包
    while (work_done < budget) {
        if (my_net_device_rx(dev) < 0) {
            break;
        }
        work_done++;
    }

    if (work_done < budget) {
        napi_complete_done(napi, work_done);
    }

    return work_done;
}

// 打开设备
static int my_net_device_open(struct net_device *netdev) {
    netif_start_queue(netdev);
    printk(KERN_INFO "Network device opened\n");
    return 0;
}

// 关闭设备
static int my_net_device_stop(struct net_device *netdev) {
    netif_stop_queue(netdev);
    printk(KERN_INFO "Network device closed\n");
    return 0;
}

// 初始化网络设备
static int my_net_device_init(struct net_device *netdev) {
    ether_setup(netdev);
    netdev->netdev_ops = &(struct net_device_ops) {
        .ndo_open = my_net_device_open,
        .ndo_stop = my_net_device_stop,
        .ndo_start_xmit = my_net_device_start_xmit,
    };
    netdev->watchdog_timeo = 5 * HZ; // 设置超时
    netdev->flags |= IFF_NOARP; // 不使用 ARP
    return 0;
}

// 设备注册
static struct my_net_device *my_dev;

static int __init my_net_device_init_module(void) {
    my_dev = kmalloc(sizeof(struct my_net_device), GFP_KERNEL);
    if (!my_dev) {
        return -ENOMEM;
    }

    my_dev->netdev = alloc_netdev(0, MY_NET_DEV_NAME, NET_NAME_UNKNOWN, my_net_device_init);
    if (!my_dev->netdev) {
        kfree(my_dev);
        return -ENOMEM;
    }

    // 注册网络设备
    if (register_netdev(my_dev->netdev)) {
        free_netdev(my_dev->netdev);
        kfree(my_dev);
        return -ENODEV;
    }

    printk(KERN_INFO "Network device registered: %s\n", MY_NET_DEV_NAME);
    return 0;
}

// 卸载模块
static void __exit my_net_device_exit_module(void) {
    unregister_netdev(my_dev->netdev);
    free_netdev(my_dev->netdev);
    kfree(my_dev);
    printk(KERN_INFO "Network device unregistered\n");
}

module_init(my_net_device_init_module);
module_exit(my_net_device_exit_module);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple network device driver");


/*


ifconfig -a

*/